use anyhow::Result;
use std::sync::Arc;
use sqlx::SqlitePool;

use crate::database::repository::{PermissionRepository, SqlitePermissionRepository};
use shared::types::{UserPermission, PermissionType};

#[derive(Clone)]
pub struct PermissionService {
    permission_repo: Arc<dyn PermissionRepository>,
}

impl PermissionService {
    pub fn new(pool: SqlitePool) -> Self {
        Self {
            permission_repo: Arc::new(SqlitePermissionRepository::new(pool)),
        }
    }
    
    /// 检查用户是否有指定权限
    pub async fn check_permission(&self, user_id: i64, permission: PermissionType, path: &str) -> Result<bool> {
        let permissions = self.permission_repo.get_user_permissions(user_id).await?;
        
        for perm in permissions {
            if perm.permission_type == permission && self.path_matches(&perm.path_pattern, path) {
                return Ok(perm.granted);
            }
        }
        
        // 默认拒绝
        Ok(false)
    }
    
    /// 检查用户是否有读取权限
    pub async fn can_read(&self, user_id: i64, path: &str) -> Result<bool> {
        self.check_permission(user_id, PermissionType::Read, path).await
    }
    
    /// 检查用户是否有写入权限
    pub async fn can_write(&self, user_id: i64, path: &str) -> Result<bool> {
        self.check_permission(user_id, PermissionType::Write, path).await
    }
    
    /// 检查用户是否有删除权限
    pub async fn can_delete(&self, user_id: i64, path: &str) -> Result<bool> {
        self.check_permission(user_id, PermissionType::Delete, path).await
    }
    
    /// 检查用户是否有管理员权限
    pub async fn is_admin(&self, user_id: i64) -> Result<bool> {
        self.check_permission(user_id, PermissionType::Admin, "/").await
    }
    
    /// 创建权限
    pub async fn create_permission(&self, permission: &UserPermission) -> Result<()> {
        self.permission_repo.create_permission(permission).await
    }
    
    /// 删除权限
    pub async fn delete_permission(&self, permission_id: i64) -> Result<()> {
        self.permission_repo.delete_permission(permission_id).await
    }
    
    /// 检查路径是否匹配模式
    fn path_matches(&self, pattern: &str, path: &str) -> bool {
        if pattern == "*" || pattern == "/*" {
            return true;
        }
        
        if pattern.ends_with("*") {
            let prefix = &pattern[..pattern.len() - 1];
            return path.starts_with(prefix);
        }
        
        if pattern.contains("*") {
            return self.wildcard_match(pattern, path);
        }
        
        // 精确匹配
        pattern == path
    }
    
    /// 通配符匹配
    fn wildcard_match(&self, pattern: &str, path: &str) -> bool {
        let pattern_parts: Vec<&str> = pattern.split('*').collect();
        let path_parts: Vec<&str> = path.split('/').collect();
        
        if pattern_parts.len() != path_parts.len() {
            return false;
        }
        
        for (pattern_part, path_part) in pattern_parts.iter().zip(path_parts.iter()) {
            if !pattern_part.is_empty() && pattern_part != path_part {
                return false;
            }
        }
        
        true
    }
}
